import router, { asyncRoutes } from './router'
import NProgress from 'nprogress' // 进度条
import 'nprogress/nprogress.css' // progress bar style
import store from './store'
import getPageTitle from '@/utils/get-page-title'
const whiteList = ['/login', '/404'] // 白名单：无需登录可以查看的路由地址(白名单的地址只能是路由表里的地址，不能瞎写)

// 为何动态路由添加后,在动态路由地址上刷新会404
// 前提1:刷新时,所有代码重新执行,回归初始化
// 前提2:刷新时,路由会从根/跳转到浏览器所在的路由地址(走一次路由守卫代码)
// 动态的还未添加,所以404了
// 解决:把*路由注释,拿到这里先追加进来,再重新跳一次路由

// 问题1:右上角退出登录+重新登录,进入到首页时,网页刷新吗?不刷新
// 问题2:网页不刷新,怎么切换的页面?完全依赖路由业务场景的切换(单页面应用的好处:用户的体验更好,切换业务场景更快)
// 问题3:为何重新登录,路由定义重复了?
// 因为退出登录的时候,把token和用户信息清除了, 再登录的时候,先获取到token保存到vuex和本地,然后才是跳转路由,才执行路由守卫(所以判断token有值),但是用户的信息没有,重新请求再添加一遍筛选后的路由对象,所以导致了路由重复
// 解决:退出登录的时候,让路由也回归初始化(调用resetRoute)

// 全局路由守卫
// 登录了-不能去登录页
// 未登录-只能去登录页
// eslint-disable-next-line space-before-function-paren
router.beforeEach(async (to, from, next) => {
  NProgress.start() // 路由跳转之前把进度条打开，中断的地方关闭，跳转完关闭
  const token = store.getters.token
  if (token) {
    if (to.path === '/login') {
      next('/')
      NProgress.done()
    } else {
      // 触发请求用户信息的actions里的方法，获取用户基本资料
      // 因为不确定用户会进到哪个页面，但是无论去哪个页面都会走路由守卫，所以在这里调用actions发请求
      next() // 如果手动让cookie里token改成错的，刷新以后，vuex才会从本地取出错误token，刷新时，路由守卫会从/跳转到地址栏里的路由地址，所以先让页面跳转进去，执行下面请求会401，被动退出时才能拿到跳转后的路由地址(未遂地址给登录页面，否则next在下面，未遂地址一直是/)
      if (!store.getters.name) {
        const menus = await store.dispatch('user/getUserInfoActions')

        // 用menus权限点英文字符串和路由规则对象name匹配
        // 把所有准备好的8个路由规则对象取出,看看名字和menus里是否匹配,匹配就证明此登录的用户有这个页面的访问权限,让filter收集此路由规则对象到新数组里
        const filterList = asyncRoutes.filter(routeObj => {
          const routeName = routeObj.children[0].name.toLowerCase()
          return menus.includes(routeName)
        })
        filterList.push({ path: '*', redirect: '/404', hidden: true })
        // 始终动态添加8个路由规则的对象
        // 知识点:路由切换匹配的路由规则对象数组,存在于内存中,new Router时,有一些初始的路由规则对象,addRoutes会给路由表再额外的增加一个规则对象
        // 现象:路由规则对象添加成功,但是左侧的导航不见了
        router.addRoutes(filterList)

        // 给vuex也同步一份
        store.commit('permission/setRoutes', filterList)

        // 让路由再跳转一次,因为上面next()会导致白屏,因为放行时动态路由还没有加入到内存的路由表里
        // 所以添加完,立刻再跳转一次,让页面出现
        next({
          path: to.path,
          replace: true // 不让回退
        })
      }
    }
  } else {
    // if (to.path === '/login' || to.path === '/404')
    if (whiteList.includes(to.path)) {
      // 要去的路由地址字符串，是否在白名单数组里出现过，出现过就放行
      next()
    } else {
      next('/login')
      NProgress.done() // 中断的地方要把进度条关闭
    }
  }
})

router.afterEach((to, _from) => {
  // 后置路由守卫没有next()
  // 正常next()放行的，才会走后置守卫，关闭正常流程进度条
  document.title = getPageTitle(to.meta.title)
  NProgress.done()
})
